package content

import (
	"context"
	"gf_blog_admin/internal/dao"
	"gf_blog_admin/internal/model"
	"gf_blog_admin/internal/service"
	"gf_blog_admin/utility/utils"
	"github.com/gogf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/errors/gerror"
)

type sArticleTag struct{}

func init() {
	service.RegisterArticleTag(NewArticleTag())
}

func NewArticleTag() *sArticleTag {
	return &sArticleTag{}
}

func (s *sArticleTag) List(ctx context.Context, in *model.ArticleTagListInput) (out []*model.ArticleTagItem, total int, err error) {
	var (
		cls = dao.BlArticleTag.Columns()
		m   = dao.BlArticleTag.Ctx(ctx)
	)

	if in.Keywords != "" {
		m = m.WhereLike(cls.TagName, in.Keywords+"%")
	}

	out = make([]*model.ArticleTagItem, 0)
	err = m.OrderDesc(cls.TagSort).OrderDesc(cls.Id).
		Page(in.Page, in.PageSize).
		Fields(cls.Id, cls.TagName, cls.TagSlug, cls.TagSort, cls.TagStatus).
		ScanAndCount(&out, &total, false)
	return
}

func (s *sArticleTag) All(ctx context.Context) (out []*model.ArticleTagAllItem, err error) {
	cls := dao.BlArticleTag.Columns()
	out = make([]*model.ArticleTagAllItem, 0)
	err = dao.BlArticleTag.Ctx(ctx).
		Where(cls.TagStatus, 1).
		OrderDesc(cls.TagSort).OrderDesc(cls.Id).
		Fields(cls.Id, cls.TagName, cls.TagSlug).
		Scan(&out)
	return
}

func (s *sArticleTag) GetSelect(ctx context.Context) (out []*model.ArticleTagSelectItem, err error) {
	cls := dao.BlArticleTag.Columns()
	out = make([]*model.ArticleTagSelectItem, 0)
	err = dao.BlArticleTag.Ctx(ctx).
		OrderDesc(cls.TagSort).OrderDesc(cls.Id).
		Fields(cls.Id, cls.TagName, cls.TagSlug).
		Scan(&out)
	return
}

func (s *sArticleTag) Store(ctx context.Context, in *model.ArticleTagFormInput) (err error) {
	cls := dao.BlArticleTag.Columns()

	if err = utils.IsUnique(ctx, &dao.BlArticleTag, map[string]string{
		cls.TagName: in.TagName,
	}, "标签名已存在"); err != nil {
		return err
	}

	err = dao.BlArticleTag.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		_, err = dao.BlArticleTag.Ctx(ctx).Data(in).Insert()
		return err
	})
	return
}

func (s *sArticleTag) Update(ctx context.Context, id uint64, in *model.ArticleTagFormInput) (err error) {
	var (
		check bool
		cls   = dao.BlArticleTag.Columns()
		m     = dao.BlArticleTag.Ctx(ctx)
	)

	if err = utils.IsUnique(ctx, &dao.BlArticleTag, map[string]interface{}{
		cls.Id + " !=": id,
		cls.TagName:    in.TagName,
	}, "标签名已存在"); err != nil {
		return err
	}

	if check, err = m.Where(cls.Id, id).Exist(); err != nil {
		return err
	} else if !check {
		return gerror.New("数据不存在")
	}

	err = dao.BlArticleTag.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		_, err = m.Where(cls.Id, id).Data(in).Update()
		return err
	})
	return
}

func (s *sArticleTag) Destroy(ctx context.Context, ids []uint64) (err error) {
	var (
		check bool
		cls   = dao.BlArticleTag.Columns()
		m     = dao.BlArticleTag.Ctx(ctx)
	)

	ids = utils.UniqueIds(ids)
	if check, err = m.WhereIn(cls.Id, ids).Exist(); err != nil {
		return err
	} else if !check {
		return gerror.New("操作失败")
	}

	check, err = dao.BlArticleHasTag.Ctx(ctx).WhereIn(dao.BlArticleHasTag.Columns().TagId, ids).Exist()
	if err != nil {
		return err
	} else if check {
		return gerror.New("标签下存在关联文章不能删除！")
	}

	err = dao.BlArticleTag.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		_, err = m.WhereIn(cls.Id, ids).Delete()
		return err
	})
	return
}
